import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

class Father<T1, T2>{}

// 子类不保留父类的泛型
// 1)没有类型 擦除
class Son1 extends Father{} // 等价于 class Son extends Father<Object, Object>{}
class Son1_ <A, B> extends Father{}
// 2)具体类型
class Son2 extends Father<Integer, String>{}
class Son2_ <A, B> extends Father<Integer, String>{}

// 子类保留父类的泛型
// 1)全部保留
class Son3<T1, T2> extends Father<T1, T2>{}
class Son3_ <T1, T2, A, B> extends Father<T1, T2>{}

// 2)部分保留
class Son4<T2> extends Father<Integer, T2>{}
class Son4_<T2, A, B> extends Father<Integer, T2>{}

class Order<T>{
    public T val;
}

// SubOrder:不是泛型类
class SubOrder extends Order<Integer>{

    public void setOrderT(Integer val){
        this.val = val;
    }
}

// SubOrder1<T>: 仍然是泛型类
class SubOrder1<T> extends Order<T>{
    public void setOrderT(T val){
        this.val = val;
    }

}

public class Test {

    public void test4(){
        Object obj = null;
        String str = null;
        obj = str;

        Object[] arr1 = null;
        String[] arr2 = null;
        arr1 = arr2;

        List<Object> list1 = null;
        List<String> list2 = new ArrayList<String>();

        // 此时的list1和list2的类型不具有父子类关系
        // 编译不通过
        // list1 = list2;
    }

    public static <E> List<E> copyFromArrayToList(E[] arr){
        ArrayList<E> list = new ArrayList<>();

        for (E e : arr){
            list.add(e);
        }
        return list;
    }

    public <E> E get(int id, E e){
        E result = null;
        return result;
    }

    public void test3(){
        ArrayList<String> list1 = null;
        ArrayList<Integer> list2 = new ArrayList<Integer>();
        // 泛型不同的引用不能相互赋值
        // list1 = list2;

        // 由于子类在继承带泛型的父类时, 指明了泛型类型。 则实例化子类对象时,不需要指明泛型
        SubOrder sub1 = new SubOrder();
        sub1.setOrderT(1122);

        SubOrder1<String> sub2 = new SubOrder1<>();
        sub2.setOrderT("order2...");

    }

    public void test2(){
        ArrayList<Integer> list = new ArrayList<Integer>();
        list.add(78);
        list.add(89);
        list.add(99);
        list.add(65);

        // 编译时, 就会进行类型检查, 保证数据的安全
        // list.add("Tom");

        // 方式一
        /*for (Integer score : list){
            // 避免了强转操作
            int stuScore = score;
            System.out.println(stuScore);
        }*/

        // 方式二
        Iterator<Integer> iterator = list.iterator();
        while (iterator.hasNext()){
            int stuScore = iterator.next();
            System.out.println(stuScore);
        }
    }

    public void test1(){
        ArrayList list = new ArrayList();
        // 需求: 存放学生的成绩
        list.add(78);
        list.add(76);
        list.add(79);
        list.add(72);
        // 问题一: 类型不安全
        // list.add("Tom");

        for (Object score : list){
            // 问题二: 强转时, 如果前面执行了list.add("Tom")语句, 则可能出现ClassCastException异常
            int stuScore = (Integer)score;
            System.out.println(stuScore);
        }
    }

    public static void main(String[] args) {
        Test test = new Test();
        // test.test1();

        test.test2();

        Integer[] array = {0,1,2,3,4,5};
        List<Integer> list = Test.copyFromArrayToList(array);
        System.out.println(list);
    }

    public static void main2(String[] args) {
        MyArray<Integer> myArray = new MyArray<>();
        myArray.setArray(0, 10);
        myArray.setArray(1, 20);
        int ret = myArray.getArray(1);

        // myArray.setArray(2,"world"); //err
    }

    public static void main1(String[] args) {
        /*MyArray myArray = new MyArray();
        myArray.setArray(0, 10);
        myArray.setArray(1, "hello");

        String ret = (String) myArray.getArray(1);*/

    }
}
